package com.sky.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.NumberUtil;
import com.sky.constant.StatusConstant;
import com.sky.dto.GoodsSalesDTO;
import com.sky.mapper.ReportMapper;
import com.sky.service.ReportService;
import com.sky.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class ReportServiceImpl implements ReportService {

    @Autowired
    private ReportMapper reportMapper;

    // 营业额统计
    @Override
    public TurnoverReportVO turnoverStatistics(LocalDate begin, LocalDate end) {
        //1. 计算时间范围 2024-02-26 2024-02-27  2024-02-28  2024-02-29
        List<LocalDate> dateList = getDateList(begin, end);
        //2. 准备数据变量
        List<Double> turnoverList = new ArrayList<>();
        //3. 查询sql凑数据
        dateList.stream().forEach(date -> {
            Double turnover = reportMapper.sumOrderAmountByStatusAndDate(5, date);
            turnoverList.add(turnover);
        });
        //4. 准备vo并返回数据
        TurnoverReportVO vo = TurnoverReportVO.builder()
                .dateList(CollUtil.join(dateList, ",")) // 2024-02-26,2024-02-27,2024-02-28,2024-02-29
                .turnoverList(CollUtil.join(turnoverList, ","))// 900.00,135.25,188.22,199.35
                .build();
        return vo;
    }

    // 用户统计
    @Override
    public UserReportVO userStatistics(LocalDate begin, LocalDate end) {
        //1. 计算日期范围
        List<LocalDate> dateList = getDateList(begin, end);
        //2. 准备数据变量
        List<Integer> newUserList = new ArrayList<>();// 每日新增
        List<Integer> totalUserList = new ArrayList<>();// 累计新增
        Integer totalUser = 0;// 计数器
        //3. 查询sql凑数据
        for (LocalDate date : dateList) {
            //3-1 查询每天新增用户
            Integer newUser = reportMapper.countUserByDate(date);
            newUserList.add(newUser);// 1、2、1
            //3-2 累计新增
            totalUser += newUser;//0+1、1+2、3+1
            totalUserList.add(totalUser);
        }
        //4. 封装vo并返回数据
        UserReportVO vo = UserReportVO.builder()
                .dateList(CollUtil.join(dateList, ","))// 2024-02-26,2024-02-27,2024-02-28,2024-02-29
                .newUserList(CollUtil.join(newUserList, ","))// 1、2、1
                .totalUserList(CollUtil.join(totalUserList, ","))// 1、3、4
                .build();
        return vo;
    }

    // 订单统计
    @Override
    public OrderReportVO orderStatistics(LocalDate begin, LocalDate end) {
        //1. 计算日期范围
        List<LocalDate> dateList = getDateList(begin, end);
        //2. 准备数据变量
        List<Integer> orderCountList = new ArrayList<>();//每日订单数
        List<Integer> validOrderCountList = new ArrayList<>();//每日有效订单数
        Integer totalOrderCount = 0; // 订单总数
        Integer totalValidOrderCount = 0;// 有效订单总数
        Double orderCompletionRate = 0.0;// 订单完成率
        //3. 查询sql凑数据
        for (LocalDate date : dateList) {
            //3-1 查询每日订单数
            Integer orderCount = reportMapper.countOrderByStatusAndDate(null, date);
            orderCountList.add(orderCount);
            //3-2 累加订单总数
            totalOrderCount += orderCount;
            //3-3 查询每日有效订单数
            Integer validOrderCount = reportMapper.countOrderByStatusAndDate(5, date);
            validOrderCountList.add(validOrderCount);
            //3-4 累加有效订单总数
            totalValidOrderCount += validOrderCount;

        }
        //3-5 计算订单完成率
        if (totalValidOrderCount > 0 && totalOrderCount > 0) {
            orderCompletionRate = totalValidOrderCount * 1.0 / totalOrderCount;
            // 保留小数点4位
            orderCompletionRate = NumberUtil.round(orderCompletionRate, 4).doubleValue();
        }
        //4. 封装vo并返回数据
        OrderReportVO vo = OrderReportVO.builder()
                .dateList(CollUtil.join(dateList, ",")) // 日期
                .orderCountList(CollUtil.join(orderCountList, ","))// 每日订单
                .validOrderCountList(CollUtil.join(validOrderCountList, ","))// 每日有效订单
                .totalOrderCount(totalOrderCount)// 订单总数
                .validOrderCount(totalValidOrderCount)// 有效订单总数
                .orderCompletionRate(orderCompletionRate)// 订单wan
                .build();
        return vo;
    }

    // 销售排行top10
    @Override
    public SalesTop10ReportVO top10(LocalDate begin, LocalDate end) {
        //1. 准备数据变量
        List<String> nameList = new ArrayList<>();// 商品名称列表
        List<Integer> numberList = new ArrayList<>();// 销量列表
        //2. 查询sql凑数据
        List<GoodsSalesDTO> list = reportMapper.selectGoodsSalesTop10(begin, end);
        for (GoodsSalesDTO goodsSalesDTO : list) {
            nameList.add(goodsSalesDTO.getName()); // 添加名称
            numberList.add(goodsSalesDTO.getNumber());// 添加销量
        }
        //3. 封装vo并返回数据
        SalesTop10ReportVO vo = SalesTop10ReportVO.builder()
                .nameList(CollUtil.join(nameList, ","))// 商品名称
                .numberList(CollUtil.join(numberList, ","))// 销量
                .build();
        return vo;
    }

    // 今日数据
    @Override
    public BusinessDataVO businessData(LocalDate today) {
        //1. 查询sql凑数据
        Integer newUsers = reportMapper.countUserByDate(today);// 新增用户数
        Double turnover = reportMapper.sumOrderAmountByStatusAndDate(5, today);// 营业额
        Integer validOrderCount = reportMapper.countOrderByStatusAndDate(5, today);// 有效订单数
        Integer orderCount = reportMapper.countOrderByStatusAndDate(null, today);// 订单总数
        // 订单完成率= 有效订单数/总订单数
        Double orderCompletionRate = 0.0;
        if (validOrderCount > 0 && orderCount > 0) {
            orderCompletionRate = validOrderCount * 1.0 / orderCount;
            // 保留4位小数
            orderCompletionRate = NumberUtil.round(orderCompletionRate, 4).doubleValue();
        }

        // 平均客单价=营业额/有效订单
        Double unitPrice = 0.0;
        if (turnover > 0 && validOrderCount > 0) {
            unitPrice = turnover * 1.0 / validOrderCount;
            // 保留2位小数
            unitPrice = NumberUtil.round(unitPrice, 2).doubleValue();
        }
        //2. 封装vo并返回数据
        BusinessDataVO vo = BusinessDataVO.builder()
                .newUsers(newUsers)// 新增用户数
                .turnover(turnover)// 营业额
                .validOrderCount(validOrderCount)// 有效订单数
                .orderCompletionRate(orderCompletionRate)// 订单完成率
                .unitPrice(unitPrice)// 平均客单价
                .build();
        return vo;
    }

    // 今日订单
    @Override
    public OrderOverViewVO overviewOrders(LocalDate today) {
        //1. 查询sql凑数据 订单状态 1待付款 2待接单 3已接单 4派送中 5已完成 6已取消 7退款
        Integer allOrders = reportMapper.countOrderByStatusAndDate(null, today);// 全部订单
        Integer waitingOrders = reportMapper.countOrderByStatusAndDate(2, today);// 待接单
        Integer deliveredOrders = reportMapper.countOrderByStatusAndDate(3, today);// 待配送
        Integer completedOrders = reportMapper.countOrderByStatusAndDate(5, today);// 已完成
        Integer cancelledOrders = reportMapper.countOrderByStatusAndDate(6, today);// 已取消
        //2. 封装vo并返回数据
        OrderOverViewVO vo = OrderOverViewVO.builder()
                .allOrders(allOrders)// 全部订单
                .waitingOrders(waitingOrders)// 待接单
                .deliveredOrders(deliveredOrders)// 待配送
                .completedOrders(completedOrders)// 已完成
                .cancelledOrders(cancelledOrders)// 已取消
                .build();
        return vo;
    }

    // 抽取日期范围计算方法
    private List<LocalDate> getDateList(LocalDate begin, LocalDate end) {
        List<LocalDate> dateList = new ArrayList<>();
        LocalDate dateIndex = begin; // 循环指针
        while (!dateIndex.isAfter(end)) {
            dateList.add(dateIndex);
            dateIndex = dateIndex.plusDays(1);// 指针加1
        }
        return dateList;
    }

    //菜品和套餐概览
    @Override
    public DishOverViewVO dishAndSetmealOverview(String table) {
        //凑数据
        Integer sold = reportMapper.countByStatusAndTable(table, StatusConstant.ENABLE);
        Integer discontinued = reportMapper.countByStatusAndTable(table, StatusConstant.DISABLE);
        //封装数据，返回vo
        return DishOverViewVO.builder()
                .sold(sold)
                .discontinued(discontinued)
                .build();
    }
}
